import Singleton from "../../../../scripts/Singleton";
import { URLData } from "../../../../scripts/URLData";
import { utils } from "../../../../scripts/Utils";
import { netMgr } from "./net";
import { SeverChessPieces, ChessPoint, UserData, WSCmd, GameState, LoginReply, LoginRequest, 
    JoinRoomRequest, JoinRoomReply, GameStartReply, UserReadyReply, 
    UserReadyRequest, DropChessRequest, DropChessReply, 
    UserInfo,
    SeatType,
    ReadyState,
    PiecesType} from "./proto";

export class DemoServer extends Singleton<DemoServer>{
    /**棋盘大小 */
    private _gridSize:number = 8
    /**用户数据*/
    private _users:UserInfo[] = []

    /**房间号 */
    private _roomId:number = 1
    /**棋盘数据 */
    private _chessData:SeverChessPieces[][] = []

    /**当前操作 */
    private _curSeatId:SeatType = SeatType.WHITE
    /**游戏状态 */
    private _curGameState:GameState = GameState.Wait
    
    private storeKey = "storeData"
    save(){
        let data = {
            user: this._users,
            chessData: this._chessData,
            curSearId:this._curSeatId,
            curGameState:this._curGameState
        }
        localStorage.setItem(this.storeKey, JSON.stringify(data))
    }

    get(){
        let data = localStorage.getItem(this.storeKey)
        if (data && data != "") {
            let json = JSON.parse(data)
            this._users = json.user
            this._chessData = json.chessData
            this._curSeatId = json.curSearId
            this._curGameState = json.curGameState            
        }
    } 

    clear(){
        localStorage.removeItem(this.storeKey)
    }

    getUser(userId:string){
        for (let index = 0; index < this._users.length; index++) {
            const element = this._users[index];
            if (element.Data.UserId  == userId) {
                return element
            }
        }
        return null
    }

    doData(cmd:string, data){
        this.get()
        let userId = URLData.userId
        if (!userId) {
            console.error("server userId error")
            return
        }
        let user = this.getUser(userId)
        
        switch (cmd) {
            case WSCmd.Login:
                this.login(data)
                break;
            case WSCmd.JoinRoom:
                this.joinRoom(data, user)
                break;
            case WSCmd.UserReady:
                this.userReady(data, user)
                break;
            case WSCmd.DropChess:
                this.drop(data, user)
                break;
            default:
                break;
        }
        this.save()
    }

    /**用户登录 */
    login( reqData: LoginRequest ){
        if (this._users.length > 2) {
            console.error("坐位已满")
            return null
        }
        
        let idx = this._users.length
        let seatId =  this._users.length + 1
        let oldUser = this.getUser(reqData.WXCode)
        if(oldUser){
            seatId = oldUser.SeatId
            idx = seatId - 1
        }else{
            this._users[idx] = this._users[idx] || {} as any
        }
       
        let user: UserData = {}
        user.UserId = reqData.WXCode
        user.HeadUrl = reqData.HeadUrl
        user.NickName = reqData.NickName
        user.Score = 1000

        this._users[idx].SeatId = seatId
        this._users[idx].Data = user
        this._users[idx].ReadyState = ReadyState.WAIT
        this._users[idx].LeftTime = 25*60
        this._users[idx].PiecesType = seatId - 1
        
        let retData: LoginReply = {
            Token: "",
            User: user,
            RoomList: [],
            RoomId: this._roomId
        } 
        console.log("用户", this._users)
        netMgr.doMessage(WSCmd.Login, retData)
    }

    /**进入房间 */
    joinRoom( reqData: JoinRoomRequest , user: UserInfo){
        if ( reqData.RoomId == this._roomId ) {
            let retData: JoinRoomReply = { }
            retData.UserList = [user]
            
            netMgr.doMessage(WSCmd.JoinRoom, retData)
            if (this._users.length == 2) {
                this.sendGameState()
            }
        }
    }

    sendGameState(){
        let gameData:GameStartReply = {
            ChessData:this._chessData,
            State:this._curGameState,
            CurOptUser:this._curSeatId,
            Users:this._users
        }
        netMgr.doMessage(WSCmd.GameStart,gameData)
    }

    /**用户准备 */
    userReady(reqData:UserReadyRequest, user: UserInfo){
        let seatId = user.SeatId
        if (this._users[seatId-1].ReadyState == ReadyState.READY) {
            console.log("已经准备", seatId)
            return
        }
        this._users[seatId-1].ReadyState = ReadyState.READY
        let retData:UserReadyReply = {
            State: this._users[seatId-1].ReadyState,
            SeatId: seatId
        }
        netMgr.doMessage(WSCmd.UserReady, retData)

        if (this._users.length == 2 && this._users[0].ReadyState == this._users[1].ReadyState) {
            console.log("都准备完毕,游戏开始")
            this._curGameState = GameState.DropPieces
            //游戏开始
            this.sendGameState()
        }
    }

    /**重置棋盘 */
    resetChess(){
        for (let row = 0; row < this._gridSize; row++) {
            this._chessData[row] = []
            for (let col = 0; col < this._gridSize; col++) {
                this._chessData[row][col] = SeverChessPieces.NONE
            }
        }
    }

    /**落子 */
    drop(reqData:DropChessRequest, user:UserInfo){
        if (this._curSeatId != user.SeatId) {
            console.error("server 不该你操作", user.SeatId)
            return false
        }
        
        let points = reqData.Point
        for (let index = 0; index < points.length; index++) {
            const point = points[index];
            if (this._chessData[point.Row][point.Col] != SeverChessPieces.NONE) {
                console.error("此落点不为空", point)
                return false
            }
        }
        
        let targetPoint = points[points.length - 1]
        if (user.PiecesType == PiecesType.BLACK) {
            this._chessData[targetPoint.Row][targetPoint.Col] = SeverChessPieces.BLACK
        }else if(user.PiecesType == PiecesType.WHITE) {
            this._chessData[targetPoint.Row][targetPoint.Col] = SeverChessPieces.WHITE
        }
        let next = this._curSeatId + 1
        if (next > SeatType.WHITE) {
            next = SeatType.BLACK
        }
        user.LeftTime -= 1
        let retData : DropChessReply = {
            Point:points,
            KillPoint:[],
            State: this._curGameState,
            ChessData: this._chessData,
            CurOptUser: this._curSeatId,
            NextOptUser: next,
            Timestamp: user.LeftTime,
            CanKillCount:0
        }
        this._curSeatId = next
        netMgr.doMessage(WSCmd.DropChess, retData)
    }

    aiDrop(){
        let nonePoints:ChessPoint[] = []
        for (let row = 0; row < this._gridSize; row++) {
            for (let col = 0; col < this._gridSize; col++) {
                const element = this._chessData[row][col];
                if (element == SeverChessPieces.NONE) {
                    nonePoints.push({
                        Row:row, Col:col
                    })
                }
            }
        }
        let noneCount = nonePoints.length 
        if (noneCount > 0) {
            let point = nonePoints[utils.GetRandom()%noneCount] 

        }

    }
    /**落子 返回移动过的坐标点*/
    move(originPoint:ChessPoint, targetPoint:ChessPoint[], seatId:SeatType){
        if (this._curSeatId != seatId) {
            console.error("server 不该你操作", seatId)
            return null
        }
        for (let index = 0; index < targetPoint.length; index++) {
            const element = targetPoint[index];
            if (this._chessData[element.Row][element.Col] != SeverChessPieces.NONE) {
                console.error("server 有目标点不为空", element)
                return null
            }
        }
        
        /**移动吃子 TODO */
        
        // this._chessData[targetPoint.Row][targetPoint.Col] = this._chessData[originPoint.Row][originPoint.Col]
        // this._chessData[originPoint.Row][originPoint.Col] = null
        
        return {
            movePoint:[],
            originPoint:originPoint,
            killPoint:[],
        }
    }

    /**判断输赢 */
    checkWinOrLose(){

        return null
    }
}